/// <reference types="@nasl/types" />

namespace nasl.ui {
  @IDEExtraInfo({
    order: 3,
    ideusage: {
      idetype: 'container',
      structured: true,
      childAccept: "['el-sub-menu', 'el-menu-item', 'el-menu-item-group'].includes(target.tag)",
      events: {
        click: true,
      },
      dataSource: {
        dismiss:
          "!this.getAttribute('dataSource') && this.getDefaultElements().length > 0",
        display: 3,
        loopRule: 'nth-last-child(-n+2)',
        loopElem: ".el-tabs__nav > .el-tabs__item",
        propertyName: ':dataSource',
        displayData: "\"[{label: '菜单一', value: '0'},{label:'菜单二', value: '1'}, {label:'菜单三', value: '2'}]\"",
      },
      additionalAttribute: {
        ':collapseTransition': '"false"',
        menuTrigger: 'click',
        ":showInDesigner": "\"true\"",
      },
      snippetsDisplayConditions: {
        default: "this.getAttribute('mode')?.value === 'vertical' ? [0, 1, 2] : [0, 1]",
      },
      displaySlotConditions: {
        left: "this.getAttribute('mode')?.value === 'horizontal'",
        right: "this.getAttribute('mode')?.value === 'horizontal'",
      },
    },
  })
  @Component({
    title: '导航菜单',
    icon: 'navbar-multi',
    description: '为网站提供导航功能的菜单。',
    group: 'Navigation',
  })
  export class ElMenu<T, V> extends ViewComponent {
    @Method({
      title: '重新加载',
      description: '清除缓存，重新加载',
    })
    reload(): void {}

    constructor(options?: Partial<ElMenuOptions<T, V>>) {
      super();
    }

    @Method({
      title: '展开',
      description: '展开指定的 sub-menu',
    })
    open(
      @Param({
        title: '子菜单唯一标识',
      })
      index: nasl.core.String,
    ): void {}

    @Method({
      title: '收起',
      description: '收起指定的 sub-menu',
    })
    close(
      @Param({
        title: '子菜单唯一标识',
      })
      index: nasl.core.String,
    ): void {}
  }

  export class ElMenuOptions<T, V> extends ViewComponentOptions {
    @Prop<ElMenuOptions<T, V>, 'mode'>({
      group: '主要属性',
      title: '模式',
      description: '模式',
      setter: {
        concept: 'EnumSelectSetter',
        options: [{ title: '水平' }, { title: '垂直' }],
      },
      onChange: [
        {
         clear: ['collapse'], 
          if: (_) => _ === 'horizontal',
        },
      ],
    })
    mode: 'horizontal' | 'vertical' = 'vertical';

    @Prop({
      group: '数据属性',
      title: '数据源',
      description: '树数据',
      designerValue: [{}, {}, {}],
      bindOpen: true,
    })
    dataSource: nasl.collection.List<T> | { list: nasl.collection.List<T>; total: nasl.core.Integer };

    @Prop({
      group: '数据属性',
      title: '数据类型',
      description: '数据源返回的数据结构的类型，自动识别类型进行展示说明',
      docDescription: '该属性为只读状态，当数据源动态绑定集合List<T>后，会自动识别T的类型并进行展示',
    })
    dataSchema: T;

    @Prop({
      group: '数据属性',
      title: '值字段',
      description: '值字段',
      setter: { concept: 'PropertySelectSetter' },
    })
    valueField: (item: T) => V;

    @Prop({
      group: '数据属性',
      title: '父级值字段',
      description: '如果数据源是平铺结构，需要指定父级字段',
      docDescription: '集合的元素类型中，用于标识父级字段的属性，支持自定义变更',
      setter: { concept: 'PropertySelectSetter' },
    })
    parentField: (item: T) => V;

    @Prop({
      group: '数据属性',
      title: '文本字段',
      description: '集合的元素类型中，用于显示文本的属性名称',
      setter: { concept: 'PropertySelectSetter' },
    })
    textField: (item: T) => any;

    @Prop<ElMenuOptions<T, V>, 'collapse'>({
      group: '主要属性',
      title: '折叠状态',
      description: '是否水平折叠收起菜单（仅在 mode 为 vertical 时可用）',
      setter: { concept: 'SwitchSetter' },
      if: (_) => _.mode === 'vertical',
    })
    collapse: nasl.core.Boolean = false;

    @Prop({
      group: '主要属性',
      title: '是否使用 vue-router 的模式',
      description:
        '是否使用 vue-router 的模式，启用该模式会在激活导航时以 index 作为 path 进行路由跳转',
      setter: { concept: 'SwitchSetter' },
    })
    router: nasl.core.Boolean = false;

    @Prop({
      group: '样式属性',
      title: '背景色',
      description: '菜单的背景色（仅支持 hex 格式）',
      setter: { concept: 'InputSetter' },
    })
    backgroundColor: nasl.core.String = '#ffffff';

    @Prop({
      group: '样式属性',
      title: '文字颜色',
      description: '菜单的文字颜色（仅支持 hex 格式）',
      setter: { concept: 'InputSetter' },
    })
    textColor: nasl.core.String = '#303133';

    @Prop({
      group: '样式属性',
      title: '当前激活菜单的文字颜色',
      description: '当前激活菜单的文字颜色（仅支持 hex 格式）',
      setter: { concept: 'InputSetter' },
    })
    activeTextColor: nasl.core.String = '#409EFF';

    @Prop({
      group: '主要属性',
      title: '当前激活菜单的标识',
      description: '当前激活菜单的 标识',
      setter: { concept: 'InputSetter' },
    })
    defaultActive: nasl.core.String;

    @Prop({
      group: '主要属性',
      title: '当前打开的子菜单的标识的数组',
      description: '当前打开的子菜单的标识的数组',
      setter: { concept: 'InputSetter' },
    })
    defaultOpeneds: nasl.collection.List<nasl.core.String>;

    @Prop({
      group: '主要属性',
      title: '是否只保持一个子菜单的展开',
      description: '是否只保持一个子菜单的展开',
      setter: { concept: 'SwitchSetter' },
    })
    uniqueOpened: nasl.core.Boolean = false;

    @Prop<ElMenuOptions<T, V>, 'menuTrigger'>({
      group: '主要属性',
      title: '子菜单打开的触发方式',
      description: '子菜单打开的触发方式(只在 mode 为 horizontal 时有效)',
      setter: {
        concept: 'EnumSelectSetter',
        options: [{ title: '鼠标悬停时' }, { title: '鼠标点击时' }],
      },
      if: (_) => _.mode === 'horizontal',
    })
    menuTrigger: 'hover' | 'click' = 'hover';

    @Prop({
      group: '主要属性',
      title: '是否开启折叠动画',
      description: '是否开启折叠动画',
      setter: { concept: 'SwitchSetter' },
    })
    collapseTransition: nasl.core.Boolean = true;

    @Event({
      title: '菜单激活时',
      description: '菜单激活回调',
    })
    onSelect: (event: { index: nasl.core.String; oldIndex: nasl.core.String }) => void;

    @Event({
      title: '子菜单展开时',
      description: '子菜单展开的回调',
    })
    onOpen: (event: { index: nasl.core.String; oldIndex: nasl.core.String }) => void;

    @Event({
      title: '子菜单收起时',
      description: '子菜单收起的回调',
    })
    onClose: (event: { index: nasl.core.String; oldIndex: nasl.core.String }) => void;

    @Event({
      title: '点击',
      description: '在元素上按下并释放任意鼠标按钮时触发。',
    })
    onClick: (event: MouseEvent) => any;

    @Event({
      title: '双击',
      description: '在元素上双击鼠标按钮时触发。',
    })
    onDblclick: (event: MouseEvent) => any;

    @Event({
      title: '右键点击',
      description: '在右键菜单显示前触发。',
    })
    onContextmenu: (event: MouseEvent) => any;

    @Event({
      title: '鼠标按下',
      description: '在元素上按下任意鼠标按钮时触发。',
    })
    onMousedown: (event: MouseEvent) => any;

    @Event({
      title: '鼠标释放',
      description: '在元素上释放任意鼠标按钮时触发。',
    })
    onMouseup: (event: MouseEvent) => any;

    @Event({
      title: '鼠标移入',
      description: '鼠标移入元素时触发。',
    })
    onMouseenter: (event: MouseEvent) => any;

    @Event({
      title: '鼠标移出',
      description: '鼠标移出元素时触发。',
    })
    onMouseleave: (event: MouseEvent) => any;

    @Event({
      title: '聚焦时',
      description: '聚焦时触发',
    })
    onFocus: (event: FocusEvent) => void;

    @Event({
      title: '失焦时',
      description: '失焦时触发',
    })
    onBlur: (event: FocusEvent) => void;

    @Slot({
      title: '默认',
      description: '默认',
      snippets: [
        {
          title: '子菜单',
          code: '<el-sub-menu><template #title><el-text text="子菜单"></el-text></template><template #default><el-menu-item><template #default><el-text text="菜单项"></el-text></template></el-menu-item></template></el-sub-menu>',
        },
        {
          title: '菜单项',
          code: '<el-menu-item><template #default><el-text text="菜单项"></el-text></template></el-menu-item>',
        },
        {
          title: '菜单组',
          code: '<el-menu-item-group><template #title><el-text text="菜单分组"></el-text></template><template #default><el-menu-item><template #default><el-text>菜单项</el-text></template></el-menu-item></template></el-menu-item-group>',
        },
      ],
    })
    slotDefault: () => Array<ViewComponent>;

    @Slot({
      title: '导航栏左侧',
      description: '导航栏左侧',
    })
    slotLeft: () => Array<ViewComponent>;

    @Slot({
      title: '导航栏右侧',
      description: '导航栏右侧',
    })
    slotRight: () => Array<ViewComponent>;
  }

  @IDEExtraInfo({
    ideusage: {
      idetype: 'container',
      structured: true, // 配合默认插槽 snippets选项 添加子组件
      parentAccept: "target.tag === 'el-menu' || target.tag === 'el-sub-menu' || target.tag === 'el-menu-item-group'",
      childAccept: "['el-sub-menu', 'el-menu-item', 'el-menu-item-group'].includes(target.tag)",
      events: {
        click: true,
      },
      displaySlotInline: {
        title: true,
      },
      snippetsDisplayConditions: {
        default: "this.getAncestor('el-menu')?.getAttribute('mode')?.value === 'vertical' ? [0, 1, 2] : [0, 1]",
      },
      forceRefresh: 'parent',
    },
  })
  @Component({
    title: '子菜单',
    description: '子菜单',
  })
  export class ElSubMenu extends ViewComponent {
    constructor(options?: Partial<ElSubMenuOptions>) {
      super();
    }
  }

  export class ElSubMenuOptions extends ViewComponentOptions {
    @Prop({
      group: '数据属性',
      title: '唯一标识',
      description: '唯一标识',
      setter: { concept: 'InputSetter' },
    })
    index: nasl.core.String | null = null;

    @Prop({
      group: '主要属性',
      title: '展开子菜单的延时',
      description: '展开子菜单的延时',
      setter: { concept: 'NumberInputSetter' },
    })
    showTimeout: nasl.core.Decimal = 300;

    @Prop({
      group: '主要属性',
      title: '隐藏子菜单的延时',
      description: '隐藏子菜单的延时',
      setter: { concept: 'NumberInputSetter' },
    })
    hideTimeout: nasl.core.Decimal = 300;

    @Prop({
      group: '状态属性',
      title: '是否禁用',
      description: '是否禁用',
      setter: { concept: 'SwitchSetter' },
    })
    disabled: nasl.core.Boolean = false;

    @Prop({
      group: '状态属性',
      title: '是否将弹出菜单插入至 body 元素',
      description: '是否将弹出菜单插入至 body 元素。在菜单的定位出现问题时，可尝试修改该属性',
      setter: { concept: 'SwitchSetter' },
    })
    popperAppendToBody: nasl.core.Boolean;

    @Slot({
      title: '默认',
      description: '默认',
      snippets: [
        {
          title: '子菜单',
          code: '<el-sub-menu><template #title><el-text text="子菜单"></el-text></template><template #default><el-menu-item><template #default><el-text text="菜单项"></el-text></template></el-menu-item></template></el-sub-menu>',
        },
        {
          title: '菜单项',
          code: '<el-menu-item><template #default><el-text text="菜单项"></el-text></template></el-menu-item>',
        },
        {
          title: '菜单组',
          code: '<el-menu-item-group><template #title><el-text text="菜单分组"></el-text></template><template #default><el-menu-item><template #default><el-text>菜单项</el-text></template></el-menu-item></template></el-menu-item-group>',
        },
      ],
    })
    slotDefault: () => Array<ViewComponent>;

    @Slot({
      title: '标题',
      description: '标题',
    })
    slotTitle: () => Array<ViewComponent>;
  }

  @IDEExtraInfo({
    ideusage: {
      idetype: 'container',
      parentAccept: "target.tag === 'el-menu' || target.tag === 'el-sub-menu' || target.tag === 'el-menu-item-group'",
    },
  })
  @Component({
    title: '菜单项',
    description: '菜单项',
  })
  export class ElMenuItem extends ViewComponent {
    constructor(options?: Partial<ElMenuItemOptions>) {
      super();
    }
  }
  export class ElMenuItemOptions extends ViewComponentOptions {
    @Prop({
      group: '数据属性',
      title: '唯一标识',
      description: '唯一标识',
      setter: { concept: 'InputSetter' },
    })
    index: nasl.core.String;

    @Prop({
      group: '交互属性',
      title: '链接地址',
    })
    hrefAndTo: nasl.core.String;

    @Prop({
      group: '状态属性',
      title: '是否禁用',
      description: '是否禁用',
      setter: { concept: 'SwitchSetter' },
    })
    disabled: nasl.core.Boolean = false;

    @Event({
      title: '点击时',
      description: '点击时触发',
    })
    onClick: (event: MouseEvent) => void;

    @Event({
      title: '双击',
      description: '在元素上双击鼠标按钮时触发。',
    })
    onDblclick: (event: MouseEvent) => any;

    @Event({
      title: '右键点击',
      description: '在右键菜单显示前触发。',
    })
    onContextmenu: (event: MouseEvent) => any;

    @Event({
      title: '鼠标按下',
      description: '在元素上按下任意鼠标按钮时触发。',
    })
    onMousedown: (event: MouseEvent) => any;

    @Event({
      title: '鼠标释放',
      description: '在元素上释放任意鼠标按钮时触发。',
    })
    onMouseup: (event: MouseEvent) => any;

    @Event({
      title: '鼠标移入',
      description: '鼠标移入元素时触发。',
    })
    onMouseenter: (event: MouseEvent) => any;

    @Event({
      title: '鼠标移出',
      description: '鼠标移出元素时触发。',
    })
    onMouseleave: (event: MouseEvent) => any;

    @Event({
      title: '聚焦时',
      description: '聚焦时触发',
    })
    onFocus: (event: FocusEvent) => void;

    @Event({
      title: '失焦时',
      description: '失焦时触发',
    })
    onBlur: (event: FocusEvent) => void;

    @Slot({
      title: '菜单项内容',
      description: '菜单项内容',
    })
    slotDefault: () => Array<ViewComponent>;
  }

  @IDEExtraInfo({
    ideusage: {
      idetype: 'container',
      structured: true,
      childAccept: "['el-sub-menu', 'el-menu-item', 'el-menu-item-group'].includes(target.tag)",
      parentAccept: "target.tag === 'el-menu' || target.tag === 'el-sub-menu' || target.tag === 'el-menu-item-group'",
      displaySlotInline: {
        title: true,
      },
    },
  })
  @Component({
    title: '菜单组',
    description: '菜单组',
  })
  export class ElMenuItemGroup extends ViewComponent {
    constructor(options?: Partial<ElMenuItemGroupOptions>) {
      super();
    }
  }
  export class ElMenuItemGroupOptions extends ViewComponentOptions {

    @Slot({
      title: '默认',
      description: '默认',
      snippets: [
        {
          title: '子菜单',
          code: '<el-sub-menu><template #title><el-text text="子菜单"></el-text></template><template #default><el-menu-item><template #default><el-text text="菜单项"></el-text></template></el-menu-item></template></el-sub-menu>',
        },
        {
          title: '菜单项',
          code: '<el-menu-item><template #default><el-text text="菜单项"></el-text></template></el-menu-item>',
        },
      ],
    })
    slotDefault: () => Array<ViewComponent>;

    @Slot({
      title: '标题',
      description: '标题',
    })
    slotTitle: () => Array<ViewComponent>;
  }
}
